/**
 * Created by Administrator on 2017/1/16.
 */

var MJPlayer = require('../MJ/player').MJPlayer;
var MJ = require('../MJ/MJ');
var Const = require('./const');
var SubCode = require('../subCode');

exports.WWMJPlayer = MJPlayer.extend({
   // _selectPiao: 0,
    _selectLaZhuang : 0,
    _isBaoHu: 0,
    _jiang: 0,
    _hundiao: false,
    _iskt: false,
    //_suhu: false,
    hunyou : 0,
    jmg: false,
    init: function(uid, msg) {
        this._super(uid, msg);

        this._stat.zmCount = 0;             // 自摸次数
        this._stat.dpCount = 0;             // 点炮次数
        this._stat.dhCount = 0;             // 点胡次数
        this._stat.anGangCount = 0;        // 暗杠次数
        this._stat.mingGangCount = 0;      // 明杠次数
        this._stat.roundanGang = 0;        // 本轮暗杠次数
        this._stat.roundmingGang = 0;      // 本轮明杠次数
        this._stat.lzCount = 0;             // 庄家次数
        this._stat.roundRules = {};         //规则
        this._selectLaZhuang = -1;                 //选择拉庄-1/0/1 未选择/不拉/拉
        this._stat.LaZhuangScore = 0;            //拉庄分数
        this._isBaoHu = false;                  //宝牌胡牌
        this._jiang = 0;                        //金牌
        this._hundiao = false;                 //混调
        this._iskt = false;                     //扣听
        this.hunyou = 0;                        //混悠
        this.jmg = false;
        // this._stat.roundPiaoScore = 0;     // 飘分

     //   this._selectPiao = -1;               // 选择飘 -1/0/1 未选择/不飘/飘
    },

   isLaZhuang: function() {
        return this._selectLaZhuang == 1;
    },

   /*setLaZhuang: function(piao) {
        this._selectLaZhuang = (piao) ? 1 : 0;
    },*/

    isLaZhuangSelected: function() {
        return this._selectLaZhuang != -1;
    },
    settlementLaZhuangScore: function() {
        var room = this.getRoom();
        if(this.getIndex() == room.getFirstHuPlayerIndex() || this.getIndex() == room.getDealerIndex()){
            return;
        }
        var score = this._stat.LaZhuangScore;
        this.addRoundScore(-score);
    },
    settlementGangScore: function() {
        var player = this;
        var room = this.getRoom();

        /*if (!this.isRoundHu()) {
            return;
        }*/
        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type) {
                if(gangInfo.type == 5){
                    this._stat.roundRules[Const.ScoreRule.JAG] = 1;
                }else if(gangInfo.type == 6){
                    this._stat.roundRules[Const.ScoreRule.JMG] = 1;
                    this.jmg = true;
                }
            } else {
                if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                    this._stat.roundanGang++;
                } else {
                    this._stat.roundmingGang++;
                }
            }
        }
        var totalGangScore = (this._stat.roundanGang * 2) + this._stat.roundmingGang;
        player.addRoundGangScore(totalGangScore);

        var GangScre = this._stat.roundGangScore;
        if (!this.isRoundHu()) {
            if(this._stat.roundRules[Const.ScoreRule.JAG]){
                player.addRoundItemScores(Const.ScoreRule.JAG, Const.ItemScore[Const.ScoreRule.JAG]);
                GangScre += Const.ItemScore[Const.ScoreRule.JAG];
            }else if(this._stat.roundRules[Const.ScoreRule.JMG]){
                player.addRoundItemScores(Const.ScoreRule.JMG, Const.ItemScore[Const.ScoreRule.JAG]);
                GangScre += Const.ItemScore[Const.ScoreRule.JMG];
            }
        }

        room.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex == player.getIndex()) {
                return;
            }
            ePlayer.addRoundScore(-GangScre);
            player.addRoundScore(GangScre);
        });
    },
    settlementPatternScore: function() {
        if (!this.isRoundHu()) {
            return;
        }

        var player = this;
        var room = this.getRoom();
        var hunyou = Const.ScoreRule.HunYou;
        var hunyouScore = player.hunyou;
        var ItemScore = 0;
        if(this._stat.roundPattern != Const.Pattern.HUNGANG){
            ExObject.eachKeyNum(this._stat.roundRules, function(rule, value) {
                if(rule == hunyou) {
                    player.addRoundItemScores(rule, Const.ItemScore[rule] * hunyouScore);
                }else {
                    player.addRoundItemScores(rule, Const.ItemScore[rule]);
                }
                player.setRoundScoreRule(rule);
            });
            ItemScore = player.getRoundItemScore();
        }
        var isDPQB = room.getOption("DPQB");

        //var GangScre = this._stat.roundGangScore;

        var PatternScore = 0;
        //计算玩家分数
        if(player._stat.roundPattern == Const.Pattern.NORMAL){
            if(ItemScore > 0){
                player._stat.roundPattern = Const.Pattern.NONE;
            }
        }else{
            PatternScore = player.getRoundPatternScore();
        }

        //拉庄分数

        // 结算牌型及基础分
        room.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex == player.getIndex()) {
                return;
            }
            var score = 1;
            score += PatternScore;
            score += ItemScore;
            //score += GangScre;
            var curPlayer = room.getPlayerByIndex(eIndex);
            ePlayer.addRoundScore(-score);
            player.addRoundScore(score);
            if(player.getIndex() == room.getDealerIndex()){
                var LZscore = ePlayer._stat.LaZhuangScore;
                ePlayer.addRoundScore(-LZscore);
                player.addRoundScore(LZscore);
                /*ePlayer.addRoundScore(-1);
                player.addRoundScore(1);*/
                player._stat.LaZhuangScore += ePlayer._stat.LaZhuangScore;
                ePlayer._stat.LaZhuangScore = -ePlayer._stat.LaZhuangScore;
            }else{
                if(eIndex == room.getDealerIndex()){
                    var LZscore = player._stat.LaZhuangScore;
                    ePlayer.addRoundScore(-LZscore);
                    player.addRoundScore(LZscore);
                    /*ePlayer.addRoundScore(-1);
                    player.addRoundScore(1);*/
                    ePlayer._stat.LaZhuangScore = -player._stat.LaZhuangScore;
                }else {
                    ePlayer._stat.LaZhuangScore = 0;
                }
            }
        });
    },

    /**
     * 结算点炮全包
     * @param dpPlayer
     */
    settlementDPQBScore: function(dpPlayer) {
        if (!this.isRoundTing()) {
            return;
        }

        var player = this;
        var room = this.getRoom();

        var otherMenQingCount = 0;
        room.enumPlayers(function(eIndex, ePlayer) {
            if (eIndex != player.getIndex() && ePlayer._stat.roundRules[Const.ScoreRule.MenQing]) {
                otherMenQingCount++;
            }
        });

        if (otherMenQingCount + 1 == room.getMaxPlayer()) {
            if (player._stat.roundRules[Const.ScoreRule.MenQing]) {
                delete player._stat.roundRules[Const.ScoreRule.MenQing];
                player._stat.roundRules[Const.ScoreRule.SiJiaQing] = 1;
            } else {
                player._stat.roundRules[Const.ScoreRule.SanJiaQing] = 1;
            }
        }

        ExObject.each(this._stat.roundRules, function(rule, value) {
            player.addRoundItemScores(rule, Const.ItemScore[rule]);
            player.setRoundScoreRule(rule);
        });

        // 结算牌型及基础分
        var basicFan = Const.PatternScore[this.getRoundPattern()] + ExObject.sumValue(this._stat.roundItemScores);
        basicFan = Math.min(room.getOption("FAN"), basicFan);
        if (basicFan < 1) {
            return;
        }

        var target = dpPlayer;
        var allExFan = 0;
        if (target.isBaoTing()) {
            var exFan = Const.ItemScore[Const.ScoreRule.BT];
            allExFan += exFan;
            target.addRoundScoreDetail(Const.ScoreReason.BT, -exFan);
        }

        if (target.isDealer()) {
            var exFan = Const.ItemScore[Const.ScoreRule.LZ];
            allExFan += exFan;
            target.addRoundScoreDetail(Const.ScoreReason.LZ, -exFan);
        }

        target.addRoundScoreDetail(player.getRoundResult(), -basicFan);

        var score = Math.pow(2, basicFan + allExFan - 1);
        target.addRoundScore(-score);
        player.addRoundScore(score);

       /* var piaoScore = room.getOption("PIAO");
        if (player.isPiao() || target.isPiao()) {
            player._stat.roundPiaoScore += piaoScore;
            target._stat.roundPiaoScore -= piaoScore;
        }*/
    },

    settlementRules: function() {
        var rules = this._stat.roundRules;
        var room = this.getRoom();
        var player = this;

        if (!this.isRoundHu()) {
            return;
        }

        // 判断 清一色/混一色
        var colors = {};
        var existSpecGang = false;
        var existAnGang = false;
        if(this.isBaohu()){
            ExObject.eachKeyNum(this._handCards.getCards(), function(card, num) {
                if(card != room.baoCard){
                    colors[MJ.getColor(card)] = 1;
                }
            });
        }else{
            ExObject.eachKeyNum(this._handCards.getCards(), function(card, num) {
                colors[MJ.getColor(card)] = 1;
            });

        }
        if(this._stat.huCard != room.baoCard)
            colors[MJ.getColor(this._stat.huCard)] = 1;

        this._pengCards.forEach(function (card) {
            colors[MJ.getColor(card)] = 1;
        });

        this._chiCards.forEach(function(chiInfo) {
            colors[MJ.getColor(chiInfo.card)] = 1;
        });

        this._gangCards.forEach(function (gangInfo) {
            if (gangInfo.type) {
                existSpecGang = true;
            } else {
                if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                    existAnGang = true;
                }
                colors[MJ.getColor(gangInfo.card)] = 1;
            }
        });
        var colorNum = Object.keys(colors).length;
        if (colorNum == 1) {
            rules[Const.ScoreRule.QingYiSe] = 1;
        }
        //闷胡
        if(this._pengCards.length < 1 && this._stat.roundmingGang < 1 && this.jmg == false) {
            //if(this._stat.roundPattern != Const.Pattern.PAIR7)
            rules[Const.ScoreRule.MenHu] = 1;
        }
        //素胡
        if(!this.isBaohu()) {
            rules[Const.ScoreRule.SuHu] = 1;
        }
        //捉五魁
        if(player._stat.huCard == MJ.getValue(MJ.Color.WAN,5) || player._stat.huCard == room.baoCard){
            if(this.checkZwk()){
                rules[Const.ScoreRule.ZWK] = 1;

            }
        }
        //混调
        if(player._hundiao) {
            rules[Const.ScoreRule.HunDai] = 1;
        }
        //混调混
        if(player._hundiao && player._stat.huCard == room.baoCard) {
            rules[Const.ScoreRule.HDH] = 1;
        }
        //扣听
        if(player._iskt) {
            rules[Const.ScoreRule.KouTing] = 1;
        }
        //混悠
        if(player.hunyou > 0) {
            rules[Const.ScoreRule.HunYou] = 1;
        }
        //豪华七对
        if(this.getRoundPattern() == Const.Pattern.PAIR7){
            var num4 = 0;
            var num3 = 0;
            var num2 = 0;
            var num1 = 0;
            var num = 0;
            ExObject.eachKeyNum(player._handCards.getCards(), function (c, n) {
                if (c != room.baoCard) {
                    if (n == 2) {
                        num2++;
                    } else if (n == 3) {
                        num3++;
                    } else if (n == 4) {
                        num4++;
                    }else{
                        num1++;
                    }
                }
                num += n;
            });
            if(num4 > 0){
                rules[Const.ScoreRule.HHPair7] = 1;
            }
        }
        if (this.getRoundPattern() != Const.Pattern.NORMAL) { // 七对/碰碰胡 不可能有后面的规则
            return;
        }
        //一条龙
        if(this.checkOneLong()){
            rules[Const.ScoreRule.YTL] = 1;
        }
    },
    //一条龙
    checkOneLong: function(){
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;
        var cards =clone(this._handCards.getCards());
        var player = this;
        //var suhu = this._suhu;
        if(MJ.sumCardsNum(cards) < 9){
            return false;
        }
        var baocard = room.getBaoCardNum(player);
        var curBaocard = baocard;
        //遍历每个花色
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum < 6) {
                continue;
            }
            var long = false;

            for(var bn = 0; bn <= baocard; bn++) {
                var curbn = bn;
                if (colorCardsNum + curbn >= 9) {
                    long = true;
                    for (var j = MJ.getValue(color, 1), k = MJ.getValue(color, MJ.COLOR_CARD_NUM); j <= k; j++) {
                        if (!colorCards[j]) {
                            if (curbn) {
                                curbn--;
                            } else {
                                long = false;
                                break;
                            }
                        }
                    }
                    if (long) {
                        for (var ii = MJ.getValue(color, 1), ll = MJ.getValue(color, MJ.COLOR_CARD_NUM); ii <= ll; ii++) {
                            if (colorCards[ii]) {
                                cards[ii] -= 1;
                            }
                        }
                        curBaocard -= bn;
                        if(bn){
                            //suhu = false;
                        }
                        break;
                    }

                }
            }
        }
        if(long){
            var hu3x2 = false;
            for (var i = 0, l = colors.length; i < l; ++i) {
                var color = colors[i];
                var colorCards = MJ.getColorCards(cards, color);
                //如果颜色是宝牌颜色，去除宝牌再检测
                if (color == MJ.getColor(room.baoCard)) {
                    colorCards[room.baoCard] = 0;
                }
                var colorCardsNum = MJ.sumCardsNum(colorCards);
                if (colorCardsNum < 1) {
                    continue;
                }
                if(player._hundiao){
                    if(curBaocard <= 0){
                        return false;
                    }
                }
                var context = {
                    result: false,
                    hu3x2:hu3x2,
                    curbaocard:curBaocard
                };
                this.checkBaoColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
                if(!context.result){
                    return false;
                }
                hu3x2 = context.hu3x2;
                curBaocard = context.curbaocard;
            }
        }else {
            return false;
        }
        //this._suhu = suhu;
        return true;

    },
    checkZwk: function(){
        var room = this.getRoom();
        var player = this;

        var cards = this._handCards.getCards();
        var baocard = cards[room.baoCard];
        if(player._stat.huCard == 35) {
            //夹5万
            if (cards[34] || cards[36]) {
                var curbaocard = baocard;
                var newcard = clone(cards);
                var check = true;
                if (newcard[34]) {
                    newcard[34] -= 1;
                } else if (curbaocard) {
                    newcard[room.baoCard] -= 1;
                    curbaocard -= 1;
                } else {
                    check = false;
                }

                if (newcard[35]) {
                    newcard[35] -= 1;
                } else {
                    check = false;
                }

                if (newcard[36]) {
                    newcard[36] -= 1;
                } else if (curbaocard) {
                    newcard[room.baoCard] -= 1;
                    curbaocard -= 1;
                } else {
                    check = false;
                }
                if (player._stat.roundPattern == Const.Pattern.PAIR) {
                    check = false;

                }
                if (check) {
                    var pattern = this.checkHuLogic(newcard);
                    if (pattern != MJ.Pattern.NONE) {

                        return true

                    }
                }
            }
            //吊5万
            if (cards[35] > 1) {
                var newcard = clone(cards);
                var curbaocard = baocard;
                newcard[35] -= 2;
                var pattern = this.checkHuLogic(newcard);
                if (pattern != MJ.Pattern.NONE) {
                    if (player._stat.roundPattern == Const.Pattern.PAIR) {
                        curbaocard = baocard;
                        if(this.checkBaoHuBigPair(newcard, curbaocard)){
                            if(this._hundiao){
                                return false;
                            }
                            return true

                        }
                    }else {
                        return true

                    }
                }
                if (this._stat.roundPattern == Const.Pattern.PAIR7) {
                    var num = 0;
                    curbaocard = baocard;
                    if(!curbaocard){
                        curbaocard = 0;
                    }
                    if (room.baoCard == 35) {
                        curbaocard -= 2;
                        ExObject.eachKeyNum(newcard, function (c, n) {
                            if (c != room.baoCard) {
                                if (n == 2) {
                                    num += 1;
                                } else if (n == 4) {
                                    num += 2;
                                } else if (n == 3) {
                                    num += 1;
                                }
                            }
                        });
                        if (num == 6 - curbaocard) {
                            return true;
                        }
                    } else {
                        ExObject.eachKeyNum(newcard, function (c, n) {
                            if (c != room.baoCard) {
                                if (n == 2) {
                                    num += 1;
                                } else if (n == 4) {
                                    num += 2;
                                } else if (n == 3) {
                                    num += 1;
                                }
                            }
                        });
                        if (num == 6 - curbaocard) {
                            return true;
                        }
                    }
                }
            }
            if(this._hundiao){
                return true;
            }
        } else {
            if(cards[34] && cards[36]){
                var curbaocard = baocard;
                var newcard = clone(cards);
                newcard[34] -=1;
                newcard[36] -=1;
                newcard[room.baoCard] -=1;
                var pattern = this.checkHuLogic(newcard);
                if (pattern != MJ.Pattern.NONE) {
                    if (player._stat.roundPattern == Const.Pattern.PAIR) {

                    }else {
                        return true

                    }
                }
            }
            if(cards[34] || cards[36]){
                var curbaocard = baocard;
                if(baocard > 1){
                    var newcard = clone(cards);
                    if(cards[36]){
                        newcard[36] -=1;
                        newcard[room.baoCard] -=2;
                        var pattern = this.checkHuLogic(newcard);
                        if (pattern != MJ.Pattern.NONE) {
                            if (player._stat.roundPattern == Const.Pattern.PAIR) {

                            }else {
                                return true

                            }
                        }
                    }
                }
                if(baocard > 1){
                    var newcard = clone(cards);
                    if(cards[34]){
                        newcard[34] -=1;
                        newcard[room.baoCard] -=2;
                        var pattern = this.checkHuLogic(newcard);
                        if (pattern != MJ.Pattern.NONE) {
                            if (player._stat.roundPattern == Const.Pattern.PAIR) {
                            }else {
                                return true

                            }
                        }
                    }
                }
            }

            if(cards[35]) {
                var curbaocard = baocard;
                var newcard = clone(cards);
                newcard[35] -= 1;
                newcard[room.baoCard] -= 1;
                var pattern = this.checkHuLogic(newcard);
                if (pattern != MJ.Pattern.NONE) {
                    if (player._stat.roundPattern == Const.Pattern.PAIR) {
                        newcard = clone(cards);
                        curbaocard = baocard;
                        if(this.checkBaoHuBigPair(newcard, curbaocard)){
                            return true
                        }
                    }else {
                        return true

                    }
                }
                if (player._stat.roundPattern == Const.Pattern.PAIR7) {
                    var num = 0;
                    curbaocard -= 1;
                    ExObject.eachKeyNum(newcard, function(c, n) {
                        if(c != room.baoCard){
                            if (n == 2) {
                                num += 1;
                            } else if (n == 4) {
                                num += 2;
                            }else  if(n == 3){
                                num += 1;
                            }
                        }
                    });
                    if(num == 6 - curbaocard){
                        return true;
                    }
                }
            }
            /*if(this._hundiao){
                return true;
            }*/
        }
        return false;
    },
    setBaoTing: function() {
        this._isBaoTing = true;
        this._iskt = true;
    },
    settlement: function() {
        //this.addRoundScore(this._stat.roundGangScore);
        //this.addRoundScore(this._stat.roundPiaoScore);

        var room = this.getRoom();
        var jincard = room._jingCard;
        var player = this;
        for (var i = 0; i < this._pengCards.length; i++){
            if(this._pengCards[i] == jincard){
                player._stat.mingGangCount++;
            }
        }
        if (this._stat.roundResult == MJ.Result.ZM) {
            this._stat.zmCount++;
        } else if (this._stat.roundResult == MJ.Result.DH) {
            this._stat.dhCount++;
            if (this._stat.roundTarget.length > 0) {
                var dpPlayer = this.getRoom().getPlayerByIndex(this._stat.roundTarget[0]);
                if (dpPlayer) {
                    dpPlayer._stat.dpCount++;
                }
            }
        }

        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type) {
                if(gangInfo.type == 5){
                    this._stat.anGangCount++;
                }if(gangInfo.type == 6){
                    this._stat.mingGangCount++;
                }
            } else {
                if (gangInfo.gang == MJ.Gang.AN || gangInfo.gang == MJ.Gang.ANS) {
                    this._stat.anGangCount++;
                } else {
                    this._stat.mingGangCount++;
                }
            }
        }
        if (this.isDealer()) {
            this._stat.lzCount++;
        }
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/
    //断线重连信息
    getReconnectInfo: function(isSelf) {
        var info = this._super(isSelf);
        if(this.isLaZhuang()){
            info.LaZhuang = this._stat.LaZhuangScore;
        }else{
            info.LaZhuang = this._selectLaZhuang;
        }
        info.remainScore = this._stat.score;
        info.kouting = this._iskt;
        info.hundiao = this._hundiao;
        info.hunYou = this.hunyou;
        return info;
    },

    getSettlementInfo: function() {
        var info = this._super();
        info.gangCards = this._gangCards;
        info.pengCards = this._pengCards;
        info.chiCards = this._chiCards;
        info.handCards = this._handCards.getCards();
        info.kouting = this._iskt;
        info.hundiao = this._hundiao;
        info.hunyou = this.hunyou;
        info.remainScore = this._stat.score;
        info.isBaoHu = this._isBaoHu;
        info.roundanGang = this._stat.roundanGang * 2;
        info.gang = this._gangCards;
        return info;
    },

    onStartNewRound: function() {
        this._super();
        //this._selectPiao = -1;
        this._stat.roundRules = {};
        this.jmg = false;

        this._selectLaZhuang = -1;
        this._stat.LaZhuangScore = 0;
        this._iskt = false;
        this._hundiao = false;
        this.hunyou = 0;
        this._stat.roundanGang = 0;        // 本轮暗杠次数
        this._stat.roundmingGang = 0;      // 本轮明杠次数

        //this._stat.roundPiaoScore = 0;
    },

    getInitHandCardPreCards: function() {
        var room = this.getRoom();
        var preCards = [];

        var distance = this.getRoom().getIndexDistance(this.getIndex(), this.getRoom().getDealerIndex());
        if (distance == 0) {
            /*preCards.push(38);
            preCards.push(38);

            preCards.push(12);
            preCards.push(12);
            preCards.push(14);
            preCards.push(14);
            preCards.push(21);
            preCards.push(21);

            preCards.push(32);
            preCards.push(33);
            preCards.push(33);

            preCards.push(36);
            preCards.push(36);*/
        } else if (distance == 3) {
            /*preCards.push(21);
            preCards.push(22);
            preCards.push(23);
            preCards.push(24);
            preCards.push(25);
            preCards.push(26);

  ;
            preCards.push(34);
            preCards.push(36);
            preCards.push(35);

            preCards.push(37);
            preCards.push(38);
            preCards.push(39);

            preCards.push(1);
            preCards.push(1)*/

        }else if (distance == 1) {


        }

        return preCards;
    },

    gangCard: function(gangTask) {
        var selectGang = gangTask.selectGang || 0;
        if (selectGang > gangTask.gangArray.length) {
            selectGang = 0;
        }

        var selectGangTask = gangTask.gangArray[selectGang];

        if (selectGangTask.type) {
            return this._specGangCard(selectGangTask);
        } else {
            return this._super(selectGangTask);
        }
    },

    _getSpecGang: function(type) {
        var result = null;
        for (var i = 0, l = this._gangCards.length; i < l; ++i) {
            var gangInfo = this._gangCards[i];
            if (gangInfo.type == type) {
                result = gangInfo;
                break;
            }
        }
        return result;
    },

    _specGangCard: function(gangTask) {
        var gangInfo = null;
        if(gangTask.type == 5) {
            this._handCards.dianGang(gangTask.card);
        }else if(gangTask.type == 6){
            this._handCards.peng(gangTask.card);
            this.setLastPlayCardTask(MJ.Task.GANG);
        }

        gangInfo = clone(gangTask);
        delete gangInfo.playerIndex;
        this._gangCards.push(gangInfo);

        return gangInfo;
    },

    cancelLastGangForQG: function(card) {
        var gangIndex = this._gangCards.length - 1;
        if (gangIndex < 0) {
            return;
        }

        var gangInfo = this._gangCards[gangIndex];
        if (gangInfo.type) {
            if (gangInfo.buCard != card) {
                return;
            }

            if (gangInfo.buCards.length < 1) {
                return;
            }

            gangInfo.buCards.splice(gangInfo.buCards.length - 1, 1);
            gangInfo.buCard = (gangInfo.buCards.length > 0) ? gangInfo[gangInfo.buCards.length - 1] : 0;
        } else {
            return this._super(card);
        }
    },

    checkChiCondition: function(card) {
        var subConfig = this.getRoom().getSubConfig();
        var room = this.getRoom();
        var color = MJ.getColor(card);
        if (subConfig.colors.indexOf(color) == -1) {
            return false;
        }

        /*if (!MJ.isBasicColor(color)) {
            return false;
        }*/
        if(card == room.baoCard) {
            return false;
        }
        return true;
    },

    /*checkHuLogic: function(cards) {
        var pattern = MJ.Pattern.NORMAL;
        pattern = this.checkBaoHuLogic(cards);
        return pattern;
    },*/




    //检测碰牌
    checkPengWithCard: function(card) {

        if (this.getRoom().isSelectColor()) {
            if (MJ.getColor(card) == this.getSelectColor()) {
                return false;
            }
        }
        var room = this.getRoom();
        if(card == room._jingCard){
            return false;
        }
        return this._handCards.getCardNum(card) >= 2;
    },
    //检测杠牌
    checkGang: function() {
        var room = this.getRoom();
        var gangArray = [];

        var lastCard = this._handCards.getLastNewCard();
        if (this.getIndex() != room.getCurPlay() || room.getCurTask()) {
            lastCard = 0;
        }
        if (lastCard != room.baoCard) { //优先杠刚摸上的牌
            if (this._handCards.getCardNum(lastCard) == 4) {
                if(this._iskt){
                    if(this.checkHuIfGang(lastCard)){
                        gangArray.push({card:lastCard, gang:MJ.Gang.AN});
                    }
                }
                else {
                    gangArray.push({card:lastCard, gang:MJ.Gang.AN});

                }
            }
            if (this._pengCards.indexOf(lastCard) != -1) {
                if(this._iskt){
                    if(this.checkHuIfGang(lastCard)){
                        gangArray.push({card:lastCard, gang:MJ.Gang.BA});

                    }
                }
                else {
                    gangArray.push({card:lastCard, gang:MJ.Gang.BA});

                }
            }
            if(lastCard == room._jingCard){
                if (this._handCards.getCardNum(lastCard) == 3) {
                    if(this._iskt){
                        if(this.checkHuIfGang(lastCard)){
                            gangArray.push({type: 5,card:lastCard, gang:5});
                        }
                    } else {
                        gangArray.push({type: 5,card:lastCard, gang:5});
                    }
                }
            }
        }

        if (this._handCards.getCardNum(room._jingCard) == 3) {
            if(room._jingCard != lastCard){
                if(this._iskt){
                    if(this.checkHuIfGang(room._jingCard)){
                        gangArray.push({type: 5,card: room._jingCard, gang:5});
                    }
                } else {
                    gangArray.push({type: 5,card: room._jingCard, gang:5});
                }
            }
        }
        var anGangCards = this._handCards.getAnGangCards();
        if (anGangCards.length > 0) {
            if (anGangCards[0] != lastCard) {
                if(anGangCards[0] != room.baoCard){
                    var gangInfo = {card:anGangCards[0], gang:MJ.Gang.ANS};
                    if (this.getRoom().getHideOption("anGangOverdue")) {
                        if (this.getPlayHand() != this.getRoom().getCurGang()) {
                            gangInfo.overdue = true;
                        }
                    }
                    gangArray.push(gangInfo);
                }
            }
        }

        this._pengCards.forEach(function(card) {
            if (this._handCards.getCardNum(card) > 0) {
                if (card != lastCard) {
                    gangArray.push({card: card, gang:MJ.Gang.BA, overdue: true});
                }
            }
        }.bind(this));

        var from = this.getIndex();
        gangArray.forEach(function(gangInfo) {
            gangInfo.from = from;
        });

        return gangArray;
    },
    //检测杠牌
    checkGangWithCard: function(card) {
        if (this.getRoom().isSelectColor()) {
            if (MJ.getColor(card) == this.getSelectColor()) {
                return false;
            }
        }
        var room = this.getRoom();
        if(card == room._jingCard){
            return (this._handCards.getCardNum(card) == 2);
        }
        return (this._handCards.getCardNum(card) == 3);
    },
    //吃牌
    chiCard: function(chiTask) {
        var card = chiTask.card;
        var selectCard = chiTask.selectCard;
        if (!selectCard || !(chiTask.maxCards[selectCard])) {
            selectCard = 0;
            chiTask.selectCard = selectCard;
        }

        /*if (MJ.getPoint(selectCard) < 3) {
            return false;
        }

        var exist = true;
        for (var i = 0; i < 3; ++i) {
            var tmpCard = selectCard - i;
            if (tmpCard != card && this._handCards.getCardNum(tmpCard) < 1) {
                exist = false; break;
            }
        }

        if (!exist) {
            return false;
        }
        */
        var tmpCards = chiTask.maxCards[selectCard];
        for (var i = 0; i < 3; ++i) {
            var tmpCard = tmpCards[i];
            if (tmpCard != card) {
                this._handCards.delCard(tmpCard);
            }
        }

        var chiInfo = clone(chiTask);
        delete chiInfo.maxCards;
        chiInfo.selectCard = tmpCards;
        this._chiCards.push(chiInfo);

        return true;
    },
    //检测吃牌
    checkChiWithCard: function(card) {
        if (!this.checkChiCondition(card)) {
            return null;
        }
        var room = this.getRoom();
        var color = MJ.getColor(card);
        var point = MJ.getPoint(card);
        var maxCards = [];
        if (MJ.isBasicColor(color)) {
            var maxPoint = MJ.ColorCardNum[color].point;
            for (var p = 0; p < 3; ++p) {
                var tmpPoint = point + p;
                if (tmpPoint >= 3 && tmpPoint <= maxPoint) {
                    var exist = true;
                    for (var i = 0; i < 3; ++i) {
                        var tmpCard = MJ.getValue(color, tmpPoint - i);
                        if (tmpCard != card && this._handCards.getCardNum(tmpCard) < 1) {
                            exist = false;
                            break;
                        }if (tmpCard == room.baoCard) {
                            exist = false;
                            break;
                        }
                    }
                    if (exist) {
                        var curCards = [];
                        curCards.push(MJ.getValue(color, tmpPoint));
                        curCards.push(MJ.getValue(color, tmpPoint-1));
                        curCards.push(MJ.getValue(color, tmpPoint-2));
                        maxCards.push(curCards);
                    }
                }
            }
        }else{
            if(point > 4){
                for(var i = 5; i <= 7; i++){
                    if(i == point){
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if(tmpCard == room.baoCard)
                    {
                        continue
                    }
                    var isChi = false;
                    if(this._handCards.getCardNum(tmpCard) > 0){
                        for(var j = 5; j <= 7; j++){
                            if(j == point){
                                continue;
                            }
                            var curCard = MJ.getValue(color, j);
                            if(curCard == room.baoCard)
                            {
                                continue;
                            }
                            if(curCard == tmpCard)
                            {
                                continue;
                            }
                            if(this._handCards.getCardNum(curCard) > 0){
                                var curCards = [];
                                curCards.push(tmpCard);
                                curCards.push(curCard);
                                curCards.push(card);
                                maxCards.push(curCards);
                                isChi = true;
                                break;
                            }
                        }
                    }
                    if(isChi) {
                        break;
                    }
                }

            }else{
                for(var i = 1; i <= 4; i++){
                    if(i == point){
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if(tmpCard == room.baoCard) {
                        continue
                    }
                    if(this._handCards.getCardNum(tmpCard) > 0){
                        for(var j = i; j <= 4; j++){
                            if(j == point){
                                continue;
                            }
                            var curCard = MJ.getValue(color, j);
                            if(curCard == room.baoCard) {
                                continue;
                            }
                            if(curCard == tmpCard) {
                                continue;
                            }
                            if(this._handCards.getCardNum(curCard) > 0){
                                var curCards = [];
                                curCards.push(tmpCard);
                                curCards.push(curCard);
                                curCards.push(card);
                                maxCards.push(curCards);
                            }
                        }
                    }
                }

            }
        }
        return maxCards.length > 0 ? maxCards : null;
    },
    checkHuNLogic: function(cards, huCard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num = 0;

        ExObject.each(cards, function(c, n) {
            if (n == 2) {
                num2++;
            } else if (n == 3) {
                num3++;
            } else if (n == 4) {
                num4++;
            }
            num += n;
        });

        if (num == 2 && this._chiCards.length <= 0) { // 碰碰胡
            return (num2 == 1) ? Const.Pattern.PAIR : MJ.Pattern.NONE;
        }
        var newCards = clone(cards);

        if ((num2 + num4*2) == 7) { // 七对
            return Const.Pattern.PAIR7;
        }
        if (num2 == 1 && ((num3*3 + 2) == num)  && this._chiCards.length <= 0) { // 碰碰胡
            return Const.Pattern.PAIR;
        }
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;

        var pattern = MJ.Pattern.NORMAL;
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);

            if (MJ.isBasicColor(color)) {
                if (!MJ.checkHuColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards)) {
                    pattern = MJ.Pattern.NONE; break;
                }
            } else {
                var context = {
                    result: false,
                    hu3x2:false,
                    curbaocard:0
                };
                this.checkBaoPairColorCards(colorCards,context)
                if (!context.result) {
                    pattern = MJ.Pattern.NONE; break;
                }
            }
        }
        return pattern;
    },
    checkHuColorCards: function(minCard, maxCard, colorCards) {
        var colorCardsNum = MJ.sumCardsNum(colorCards);
        if (colorCardsNum == 0) {
            return true;
        }

        var context = {result: false};
        var modNum = colorCardsNum % 3;
        if (modNum == 0) {
            this.checkHu3X(minCard, maxCard, colorCards, context);
        } else if (modNum == 2) {
            this.checkHu3X2(minCard, maxCard, colorCards, context);
        }

        return context.result
    },

    checkHu3X: function(minCard, maxCard, cards, context) {
        if (MJ.sumCardsNum(cards) < 1) {
            context.result = true;
            return;
        }

        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }

            var num2 = cards[i + 1];
            var num3 = cards[i + 2];

            if (num == 3) {
                if (num2 >= 3 && num3 >= 3) {
                    var newCards = clone(cards);
                    newCards[i] = 0;
                    newCards[i + 1] = num2 - 3;
                    newCards[i + 2] = num3 - 3;
                    this.checkHu3X(minCard, maxCard, newCards, context);
                }

                cards[i] = 0;
                this.checkHu3X(minCard, maxCard, cards, context);
            } else {
                if (num2 && num3) {
                    cards[i] = num - 1;
                    cards[i + 1] = num2 - 1;
                    cards[i + 2] = num3 - 1;
                    this.checkHu3X(minCard, maxCard, cards, context);
                }
            }
            break;
        }
    },

    checkHu3X2: function(minCard, maxCard, cards, context) {
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (num >= 2) {
                var newCards = clone(cards);
                newCards[i] = num - 2;
                this.checkHu3X(minCard, maxCard, newCards, context);
                if (context.result) break;
            }
        }
    },

    checkPairHuColorCards: function(cards) {
        var num3 = 0;
        var num2 = 0;
        var numOther = 0;

        ExObject.each(cards, function(c, n) {
            if (n == 2) {
                num2++;
            } else if (n == 3) {
                num3++;
            } else {
                numOther++;
            }
        });

        if((numOther == 0) && (num2 <= 1)) {
            return true;
        }
        var context = {
            result: false,
            hu3x2:false,
            curbaocard:0
        };
        this.checkBaoPairColorCards(cards,context)
        return context.result;
    },
    checkHuIfGang: function(gangcard){
        var cards = this._handCards.getCards();
        var newcards = clone(cards);
        newcards[gangcard] = 0;
        var pattern = this.checkHuLogic(newcards);
        if(pattern != MJ.Pattern.NONE){
            return true;
        }
        return false;
    },
    //宝牌胡牌逻辑
    checkHuLogic: function(cards, huCard) {
        var room = this.getRoom();
        this._isBaoHu = false;
        var baocard = cards[room.baoCard];
        if(!baocard){
            baocard = 0;
        }
        if(baocard > 0){
            this._isBaoHu = true;
        }
        var pattern = MJ.Pattern.NONE;

        /*this._isBaoHu = this._hundiao;
        this._suhu = false;
        if(!this._isBaoHu) {
            pattern = this.checkHuNLogic(cards, huCard);
        }
        if(pattern != MJ.Pattern.NONE){
            this._suhu = true;
        }*/
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num1 = 0;
        var num = 0;
        var curBaocard = baocard;
        ExObject.eachKeyNum(cards, function (c, n) {
            if (c != room.baoCard) {
                if (n == 2) {
                    num2++;
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                }else{
                    num1++;
                }
            }
            num += n;
        });
        if (baocard == 4) {//4个宝直接胡牌
            return Const.Pattern.HUNGANG;
        }
        var newCards = clone(cards);

        newCards = clone(cards);
        if (this.checkBaoHuPair7(newCards, baocard)) { // 七对
            //._isBaoHu = true;

            return Const.Pattern.PAIR7;
        }
        newCards = clone(cards);
        if (this.checkBaoHuBigPair(newCards,baocard) && this._chiCards.length <= 0) { //// 碰碰胡
            //this._isBaoHu = true;

            return Const.Pattern.PAIR;
        }
        var colors = room.getSubConfig().colors;
        var hu3x2 = false;
        curBaocard = baocard;
        pattern = MJ.Pattern.NORMAL;

        //遍历每个花色

        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(cards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                    colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2:hu3x2,
                curbaocard:curBaocard
            };
            if (MJ.isBasicColor(color)) {
                this.checkBaoColorCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            } else {
                this.checkBaoPairColorCards(colorCards, context);
            }
            if(!context.result){
                pattern = MJ.Pattern.NONE;
                break;
            }
            hu3x2 = context.hu3x2;
            curBaocard = context.curbaocard;
        }
        return pattern;
    },

    isBaohu:function(){
       return this._isBaoHu;
    },
    //混调用3X
    checkColor3XCards: function(minCard, maxCard, cards, context){
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; bn <= context.curbaocard; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            }
        }
    },
    checkBaoColorCards: function(minCard, maxCard, cards, context){
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; bn <= context.curbaocard; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                this.checkBaoHu3X(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if(curmodNum == 2 && !context.hu3x2){
                this.checkBaoHu3X2(minCard, maxCard, cards, context, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
        }
    },
    checkBaoPairColorCards: function(cards, context) {
        var colorCardsNum = MJ.sumCardsNum(cards);
        for(var bn = 0; context.curbaocard >= bn; bn++){
            var curbn = bn;
            var curmodNum = (colorCardsNum + curbn) % 3;
            if(curmodNum == 0){
                context.result = this.checkBaoPairHuColorCards(cards, curbn);
                if (context.result) {
                    context.curbaocard -= curbn;
                    break;
                }
            } else if(curmodNum == 2 && !context.hu3x2){
                for (var i = 1; i <= 7; ++i) {
                    var num = cards[i];
                    if (num >= 2) {
                        var newCards = clone(cards);
                        newCards[i] = num - 2;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            break;
                        }
                    } else if(num == 1 && context.curbaocard) {
                        var newCards = clone(cards);
                        newCards[i] = 0;
                        curbn--;
                        context.result = this.checkBaoPairHuColorCards(newCards, curbn);
                        if (context.result) {
                            break;
                        }
                    }
                }
                if (context.result) {
                    context.curbaocard -= curbn;
                    context.hu3x2 = true;
                    break;
                }
            }
            if(context.result) {
                break;
            }
        }
    },
    checkBaoHu3X: function(minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            context.result = true;
            return;
        }
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }
            var num2 = cards[i + 1];
            var num3 = cards[i + 2];
            if (num == 3) {
                if (num2 > 0 && num3 > 0) {
                    var iTmp = 0;
                    if (num2 < 3) {
                        iTmp += 3 - num2;
                    }
                    if (num3 < 3) {
                        iTmp += 3 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 3) {
                            newCards[i + 1] = num2 - 3;
                        } else{
                            newbaocard -= 3 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 3) {
                            newCards[i + 2] = num3 - 3;
                        } else {
                            newbaocard -= 3 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                cards[i] = 0;
                this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
            } else if(num == 2){
                if (num2 > 0 && num3 > 0){
                    var iTmp = 0;
                    if (num2 < 2) {
                        iTmp += 2 - num2;
                    }
                    if (num3 < 2) {
                        iTmp += 2 - num3;
                    }
                    if (iTmp <= baocard) {
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[i] = 0;
                        if (num2 >= 2) {
                            newCards[i + 1] = num2 - 2;
                        } else{
                            newbaocard -= 2 - newCards[i + 1];
                            newCards[i + 1] = 0;
                        }
                        if (num3 >= 2) {
                            newCards[i + 2] = num3 - 2;
                        } else {
                            newbaocard -= 2 - newCards[i + 2];
                            newCards[i + 2] = 0;
                        }
                        this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                    }
                }
                if(baocard){
                    cards[i] = 0;
                    baocard--;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if(num2) {
                        newCards[i + 1] = num2 - 1;
                    }else{
                        newbaocard--;
                    }
                    if(num3){
                        newCards[i + 2] = num3 - 1;
                    }
                    else{
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if(num == 1 && baocard >= 2){
                    cards[i] = 0;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            } else {
                if (((num2 || num3) && baocard) || (num2 && num3)) {
                    var newCards = clone(cards);
                    var newbaocard = baocard;
                    newCards[i] = num - 1;
                    if(num2) {
                        newCards[i + 1] = num2 - 1;
                    }else{
                        newbaocard--;
                    }
                    if(num3){
                        newCards[i + 2] = num3 - 1;
                    }
                    else{
                        newbaocard--;
                    }
                    this.checkBaoHu3X(minCard, maxCard, newCards, context, newbaocard);
                }
                if(num && baocard >= 2){
                    cards[i] -= 1;
                    baocard -= 2;
                    this.checkBaoHu3X(minCard, maxCard, cards, context, baocard);
                }
            }
            break;
        }
    },

    checkBaoHu3X2: function(minCard, maxCard, cards, context, baocard) {
        var room = this.getRoom();
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];

            if (num >= 2) {
                var newCards = clone(cards);
                newCards[i] = num - 2;

                var newBaocard = baocard;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result){
                    context.result = true;
                    break;
                }
            } else if(num == 1 && baocard) {
                var newCards = clone(cards);
                newCards[i] = 0;
                var newBaocard = baocard;
                newBaocard--;
                this.checkBaoHu3X(minCard, maxCard, newCards, context, newBaocard);
                if (context.result){
                    context.result = true;
                    break;
                }
            }
        }
    },
    checkBaoPairHuColorCards: function(cards, baocard) {
        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var numOther = 0;
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            return true;
        }
        var newcard = baocard;
        ExObject.each(cards, function(c, n) {
            if(n == 1){
                if(newcard) {
                    newcard--;
                    num2++;
                }else{
                    numOther++;
                }
            }else if (n == 2) {
                if(newcard) {
                    newcard--;
                    num3++;
                }else{
                    num2++;
                }
            } else if (n == 3) {
                num3++;
            } else if (n == 0) {
            }else {
                numOther++;
            }
        });
        if((numOther == 0) && (num2 <= 1)) {
            return true;
        }
        var context = {result: false};
        this.checkZiCard(cards, context, baocard);
        return context.result;
    },
    checkZiCard:function(cards, context, baocard) {
        var room = this.getRoom();
        var colorCardsNum = MJ.sumCardsNum(cards);
        if (colorCardsNum < 1) {
            context.result = true;
            return;
        }
        var color = MJ.Color.ZI;

        for (var p = 1; p <= 7; ++p) {
            var num = cards[p];
            if (!num) {
                continue;
            }
            var point = p;
            if (point > MJ.ZI.BF) {
                var num2 = 0;
                var num3 = 0;
                var point2 = 0;
                var point3 = 0;
                for (var i = MJ.ZI.HZ; i <= MJ.ZI.BB; i++) {
                    if (i == point) {
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if (tmpCard == room.baoCard) {
                        continue
                    }
                    num2 = cards[tmpCard];
                    point2 = i;
                }
                for (var i = MJ.ZI.HZ; i <= MJ.ZI.BB; i++) {
                    if (i == point) {
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if (tmpCard == room.baoCard) {
                        continue
                    }
                    if (i == point2) {
                        continue;
                    }
                    num3 = cards[tmpCard];
                    point3 = i;
                }
                if (num == 3) {
                    if (num2 > 0 && num3 > 0) {
                        var iTmp = 0;
                        if (num2 < 3) {
                            iTmp += 3 - num2;
                        }
                        if (num3 < 3) {
                            iTmp += 3 - num3;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 3) {
                                newCards[point2] = num2 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num3 >= 3) {
                                newCards[point3] = num3 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    cards[point] = 0;
                    this.checkZiCard(cards, context, baocard);
                } else if (num == 2) {
                    if (num2 > 0 && num3 > 0) {
                        var iTmp = 0;
                        if (num2 < 2) {
                            iTmp += 2 - num2;
                        }
                        if (num3 < 2) {
                            iTmp += 2 - num3;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 2) {
                                newCards[point2] = num2 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num3 >= 2) {
                                newCards[point3] = num3 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if(baocard){
                        cards[point] = 0;
                        baocard--;
                        this.checkZiCard(cards, context, baocard);

                    }
                    if(num2 && num3){
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[point] = num - 1;
                        if (num2) {
                            newCards[point2] = num2 - 1;
                        }
                        if (num3) {
                            newCards[point3] = num3 - 1;
                        }
                        this.checkZiCard(newCards, context, newbaocard);
                    }
                    if(baocard > 0){
                        if(num2 || num3){
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            } else {
                                newbaocard--;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }
                            else {
                                newbaocard--;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if (num == 1 && baocard >= 2) {
                        cards[point] = 0;
                        baocard -= 2;
                        this.checkZiCard(cards, context, baocard);
                    }
                } else {
                    if(num2 && num3){
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[point] = num - 1;
                        if (num2) {
                            newCards[point2] = num2 - 1;
                        }
                        if (num3) {
                            newCards[point3] = num3 - 1;
                        }
                        this.checkZiCard(newCards, context, newbaocard);
                    }
                    if(baocard > 0){
                        if(num2 || num3){
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            } else {
                                newbaocard--;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }
                            else {
                                newbaocard--;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if (num == 1 && baocard >= 2) {
                        cards[point] = 0;
                        baocard -= 2;
                        this.checkZiCard(cards, context, baocard);
                    }
                }
                break;
            } else {
                var num2 = 0;
                var num3 = 0;
                var num4 = 0;
                var point2 = 0;
                var point3 = 0;
                var point4 = 0;
                for (var i = MJ.ZI.DF; i <= MJ.ZI.BF; i++) {
                    if (i == point) {
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if (tmpCard == room.baoCard) {
                        continue
                    }
                    num2 = cards[tmpCard];
                    point2 = i;
                }
                for (var i = MJ.ZI.DF; i <= MJ.ZI.BF; i++) {
                    if (i == point) {
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if (tmpCard == room.baoCard) {
                        continue
                    }
                    if (i == point2) {
                        continue;
                    }
                    num3 = cards[tmpCard];
                    point3 = i;
                }
                for (var i = MJ.ZI.DF; i <= MJ.ZI.BF; i++) {
                    if (i == point) {
                        continue;
                    }
                    var tmpCard = MJ.getValue(color, i);
                    if (tmpCard == room.baoCard) {
                        continue
                    }
                    if (i == point2) {
                        continue;
                    }
                    if (i == point3) {
                        continue;
                    }
                    num4 = cards[tmpCard];
                    point4 = i;
                }
                if (num == 3) {
                    if (num2 > 0 && num3 > 0 && !context.result) {
                        var iTmp = 0;
                        if (num2 < 3) {
                            iTmp += 3 - num2;
                        }
                        if (num3 < 3) {
                            iTmp += 3 - num3;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 3) {
                                newCards[point2] = num2 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num3 >= 3) {
                                newCards[point3] = num3 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if(num2 > 0 && num4 > 0 && !context.result) {
                        var iTmp = 0;
                        if (num2 < 3) {
                            iTmp += 3 - num2;
                        }
                        if (num3 < 3) {
                            iTmp += 3 - num4;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 3) {
                                newCards[point2] = num2 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num4 >= 3) {
                                newCards[point4] = num4 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point4];
                                newCards[point4] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if(num3 > 0 && num4 > 0 && !context.result) {
                        var iTmp = 0;
                        if (num3 < 3) {
                            iTmp += 3 - num3;
                        }
                        if (num4 < 3) {
                            iTmp += 3 - num4;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num3 >= 3) {
                                newCards[point3] = num3 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            if (num4 >= 3) {
                                newCards[point4] = num4 - 3;
                            } else {
                                newbaocard -= 3 - newCards[point4];
                                newCards[point4] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    cards[point] = 0;
                    this.checkZiCard(cards, context, baocard);
                } else if (num == 2) {
                    if (num2 > 0 && num3 > 0) {
                        var iTmp = 0;
                        if (num2 < 2) {
                            iTmp += 2 - num2;
                        }
                        if (num3 < 2) {
                            iTmp += 2 - num3;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 2) {
                                newCards[point2] = num2 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num3 >= 2) {
                                newCards[point3] = num3 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                        if(num2 && num3){
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }

                            this.checkZiCard(newCards, context, newbaocard);
                        }
                        if(baocard > 0){
                            if (num2 || num3) {
                                var newCards = clone(cards);
                                var newbaocard = baocard;
                                newCards[point] = num - 1;
                                if (num2) {
                                    newCards[point2] = num2 - 1;
                                } else {
                                    newbaocard--;
                                }
                                if (num3) {
                                    newCards[point3] = num3 - 1;
                                }
                                else {
                                    newbaocard--;
                                }
                                this.checkZiCard(newCards, context, newbaocard);
                            }
                        }
                    }
                    if(num2 > 0 && num4 > 0 && !context.result) {
                        var iTmp = 0;
                        if (num2 < 2) {
                            iTmp += 2 - num2;
                        }
                        if (num3 < 2) {
                            iTmp += 2 - num4;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num2 >= 2) {
                                newCards[point2] = num2 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point2];
                                newCards[point2] = 0;
                            }
                            if (num4 >= 2) {
                                newCards[point4] = num4 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point4];
                                newCards[point4] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }

                        if(num2 && num4){
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            }
                            if (num4) {
                                newCards[point4] = num4 - 1;
                            }

                            this.checkZiCard(newCards, context, newbaocard);
                        }
                        if(baocard > 0){
                            if (num2 || num4) {
                                var newCards = clone(cards);
                                var newbaocard = baocard;
                                newCards[point] = num - 1;
                                if (num2) {
                                    newCards[point2] = num2 - 1;
                                } else {
                                    newbaocard--;
                                }
                                if (num4) {
                                    newCards[point4] = num4 - 1;
                                }
                                else {
                                    newbaocard--;
                                }
                                this.checkZiCard(newCards, context, newbaocard);
                            }
                        }
                    }
                    if(num3 > 0 && num4 > 0 && !context.result) {
                        var iTmp = 0;
                        if (num3 < 2) {
                            iTmp += 2 - num3;
                        }
                        if (num4 < 2) {
                            iTmp += 2 - num4;
                        }
                        if (iTmp <= baocard) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = 0;
                            if (num3 >= 2) {
                                newCards[point3] = num3 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point3];
                                newCards[point3] = 0;
                            }
                            if (num4 >= 2) {
                                newCards[point4] = num4 - 2;
                            } else {
                                newbaocard -= 2 - newCards[point4];
                                newCards[point4] = 0;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                        if(num4 && num3){
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num4) {
                                newCards[point4] = num4 - 1;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }

                            this.checkZiCard(newCards, context, newbaocard);
                        }
                        if(baocard > 0){
                            if (num4 || num3) {
                                var newCards = clone(cards);
                                var newbaocard = baocard;
                                newCards[point] = num - 1;
                                if (num4) {
                                    newCards[point4] = num4 - 1;
                                } else {
                                    newbaocard--;
                                }
                                if (num3) {
                                    newCards[point3] = num3 - 1;
                                }
                                else {
                                    newbaocard--;
                                }
                                this.checkZiCard(newCards, context, newbaocard);
                            }
                        }
                    }
                    if(baocard){
                        cards[point] = 0;
                        baocard--;
                        this.checkZiCard(cards, context, baocard);

                    }

                } else {
                    if(num2 && num3){
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[point] = num - 1;
                        if (num2) {
                            newCards[point2] = num2 - 1;
                        }
                        if (num3) {
                            newCards[point3] = num3 - 1;
                        }

                        this.checkZiCard(newCards, context, newbaocard);
                    }
                    if(baocard > 0){
                        if (num2 || num3) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            } else {
                                newbaocard--;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }
                            else {
                                newbaocard--;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if(num2 && num4){
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[point] = num - 1;
                        if (num2) {
                            newCards[point2] = num2 - 1;
                        }
                        if (num4) {
                            newCards[point4] = num4 - 1;
                        }

                        this.checkZiCard(newCards, context, newbaocard);
                    }
                    if(baocard > 0){
                        if (num2 || num4) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num2) {
                                newCards[point2] = num2 - 1;
                            } else {
                                newbaocard--;
                            }
                            if (num4) {
                                newCards[point4] = num4 - 1;
                            }
                            else {
                                newbaocard--;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                    if(num4 && num3){
                        var newCards = clone(cards);
                        var newbaocard = baocard;
                        newCards[point] = num - 1;
                        if (num4) {
                            newCards[point4] = num4 - 1;
                        }
                        if (num3) {
                            newCards[point3] = num3 - 1;
                        }
                        this.checkZiCard(newCards, context, newbaocard);
                    }
                    if(baocard > 0){
                        if (num4 || num3) {
                            var newCards = clone(cards);
                            var newbaocard = baocard;
                            newCards[point] = num - 1;
                            if (num4) {
                                newCards[point4] = num4 - 1;
                            } else {
                                newbaocard--;
                            }
                            if (num3) {
                                newCards[point3] = num3 - 1;
                            }
                            else {
                                newbaocard--;
                            }
                            this.checkZiCard(newCards, context, newbaocard);
                        }
                    }
                }
                break;
            }
        }
    },

    checkHunDiao:function(cards){
        var room = this.getRoom();
        var newCards = clone(cards);
        var baocard = room.getBaoCardNum(this);
        if(baocard < 1){
            return false;
        }
        newCards[room.baoCard] -= 1;
        baocard -= 1;

        var num4 = 0;
        var num3 = 0;
        var num2 = 0;
        var num1 = 0;
        var num = 0;

        var curBaocard = baocard;
        //this._isBaoHu = true;
        ExObject.eachKeyNum(newCards, function (c, n) {
            if (c != room.baoCard) {
                if (n == 2) {
                    num2++;
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                }else{
                    num1++;
                }
            }
            num += n;
        });
        //七对
        if(num2 + num4 * 2 == 6 - curBaocard){
            return true;
        }
        num4 = 0;
        num3 = 0;
        num2 = 0;
        num1 = 0;
        num = 0;
        //碰碰胡
        ExObject.eachKeyNum(newCards, function (c, n) {
            if (c != room.baoCard) {
                if (n == 2) {
                    if(curBaocard){
                        curBaocard--;
                        num3++;
                    }else {
                        num2++;
                    }
                } else if (n == 3) {
                    num3++;
                } else if (n == 4) {
                    num4++;
                }else{
                    if(curBaocard >= 2){
                        curBaocard -= 2;
                        num3++;
                    }else {
                        num1++;
                    }
                }
            }
            num += n;
        });
        if(num3 * 3 == num){
            return true;
        }
        //平胡
        var colors = room.getSubConfig().colors;
        var hu3x2 = false;
        curBaocard = baocard;
        var pattern = MJ.Pattern.NORMAL;
        //遍历每个花色
        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var colorCards = MJ.getColorCards(newCards, color);
            //如果颜色是宝牌颜色，去除宝牌再检测
            if (color == MJ.getColor(room.baoCard)) {
                colorCards[room.baoCard] = 0;
            }
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum == 0) {
                continue;
            }
            var context = {
                result: false,
                hu3x2:true,
                curbaocard:curBaocard
            };

            if (MJ.isBasicColor(color)) {
                this.checkColor3XCards(MJ.getValue(color, 1), MJ.getValue(color, MJ.COLOR_CARD_NUM), colorCards, context);
            }
            if(!context.result){
                return false;
            }
            curBaocard = context.curbaocard;
        }
        return true;
    },
    /**
     * 是否可以胡13幺
     * @param cards
     */
    checkBaoHuOne13: function(cards) {
        var cardArr = Object.keys(cards);
        if (cardArr.length != 13) {
            return false;
        }

        return (cards[MJ.Value.TONG1] > 0) &&
            (cards[MJ.Value.TONG9] > 0) &&
            (cards[MJ.Value.TIAO1] > 0) &&
            (cards[MJ.Value.TIAO9] > 0) &&
            (cards[MJ.Value.WAN1] > 0) &&
            (cards[MJ.Value.WAN9] > 0) &&
            (cards[MJ.ZI.DF] > 0) &&
            (cards[MJ.ZI.NF] > 0) &&
            (cards[MJ.ZI.XF] > 0) &&
            (cards[MJ.ZI.BF] > 0) &&
            (cards[MJ.ZI.HZ] > 0) &&
            (cards[MJ.ZI.FC] > 0) &&
            (cards[MJ.ZI.BB] > 0);
    },

    checkBaoHuPair7: function(cards,baocard) {
        var room = this.getRoom();
        var num = 0;
        ExObject.eachKeyNum(cards, function(c, n) {
            if(c != room.baoCard){
                if (n == 2) {
                    num += 1;
                    cards[c] = 0;
                } else if (n == 4) {
                    num += 2;
                    cards[c] = 0;
                }else  if(n == 3){
                    num += 1;
                    cards[c] -= 2;
                }
            }
        });
       return (baocard >= 7 - num);
    },
    checkBaoHuBigPair: function(cards,baocard) {
        var num = 0;
        var num1 = 0;
        var num2 = 0;
        var num3 = 0;
        var num4 = 0;
        var card = baocard;
        var room = this.getRoom();
        ExObject.eachKeyNum(cards, function(c, n) {
            if(c != room.baoCard){
                if (n == 2) {
                    if(card){
                        card--;
                    }else{
                        num2++;
                    }
                } else if (n == 4) {
                    num4++;
                }else  if(n == 3){
                }else if(n == 1){
                    if(card){
                        card--;
                        num2++;
                    }else{
                        num1++;
                    }
                }
            }
            num++;
        });
        if(num2 == 2 && num1 == 0 && card > 0 && num4 == 0) {
            return true
        }else if(num1 == 1 && num2 == 0 && card > 0 && num4 == 0){
            return true
        }else if(num1 == 0 && num2 == 0 && num4 == 0) {
            return true;
        }else if(num2 == 1 && num1 == 0 && num4 == 0){
            return true;
        }
        return false
    },
    check13BuDa: function(cards,bao){
        var room = this.getRoom();
        var colors = room.getSubConfig().colors;
        var pattern = MJ.Pattern.NORMAL;
        var CardsNum = MJ.sumCardsNum(cards);
        if (CardsNum < 13) {
            return false;
        }
        if(bao) {
            cards[room.baoCard] = 0;
        }

        for (var i = 0, l = colors.length; i < l; ++i) {
            var color = colors[i];
            var minCard = MJ.getValue(color, 1);
            var maxCard = MJ.getValue(color, MJ.COLOR_CARD_NUM);
            var colorCards = MJ.getColorCards(cards, color);
            var colorCardsNum = MJ.sumCardsNum(colorCards);
            if (colorCardsNum < 1) {
               continue;
            }
            if (MJ.isBasicColor(color)) {
                if(!this.checkColorBuDa(minCard, maxCard, colorCards)){
                    return false;
                }
            } else {
                var num = true;
                ExObject.each(colorCards, function(c, n) {
                    if (n > 1) {
                        num = false;
                    }
                });
                if(!num){
                    return false;
                }
            }
        }
        return true;
    },
    checkColorBuDa:function(minCard, maxCard ,cards){
        for (var i = minCard; i <= maxCard; ++i) {
            var num = cards[i];
            if (!num) {
                continue;
            }
            if(num != 1){
                return false;
            }
            var num2 = cards[i + 1];
            var num3 = cards[i + 2];
            if(num2 || num3){
                return false;
            }
        }
        return true;
    },
});